package controller.reader;

import java.io.EOFException;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.ArrayList;
import java.util.Scanner;

import model.Edge;
import model.container.edges.Edges;
import model.container.vertices.Vertices;

/**
 * Controller to read data from a file,
 * and put the info into a Vertices
 *
 */
public class FromFile {
	private String filePath;
	private int nbNodes;
	private int nbEdges;
	private boolean isDirected;
	private ArrayList<Edge> tEdges = new ArrayList<Edge>();

	/**
	 * The FromFile constructor
	 * @see FromFile#FromFile(String)
	 */
	public FromFile() {
	}
	/**
	 * The FromFile constructor
	 * @param f the path to the file to read from
	 */
	public FromFile(String f) {
		setFilePath(f);
	}

	/**
	 * Fetch data from the associated file,
	 * filled up an ArrayList
	 * @throws FileNotFoundException 
	 */
	public void fetch() {
		Scanner scanner = null;

		try {
			scanner = new Scanner(new FileReader(getFilePath()));
			while(scanner.hasNextLine())
				try {
					parseLine(scanner.nextLine());
				} catch (EOFException e) {
					break;
				} catch (Exception e) {
					e.printStackTrace();
				}
			//System.out.println("[+] Edges added : "+tEdges);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} finally {
			scanner.close();
		}
	}
	
	/**
	 * Call fetch on the filename <b>f</b>
	 * @param f path to file to fetch from
	 */
	public void fetch(String f) {
		setFilePath(f);
		fetch();
	}

	/**
	 * Parse a Line from a .dat file
	 * @param l the line read from the file
	 * @return the Edge created from the line
	 */
	private void parseLine(String l) throws EOFException {
		int t2, t3;
		Scanner s = new Scanner(l);
		String t = new String();

		s.useDelimiter("[^a-zA-Z0-9_-]+");

		if(s.hasNext()) {
			t = s.next().trim();
			if(t.equals("UNDIRECTED"))
				setDirected(false);
			else if(t.equals("DIRECTED"))
				setDirected(true);
			else if(t.equals("LIST_OF_EDGES"))
				return;
			else if(t.equals("END"))
				throw new EOFException();
			else if(t.equals("NB_NODES"))
				setNbNodes(Integer.parseInt(s.next().trim()));
			else if(t.equals("NB_EDGES"))
				setNbEdges(Integer.parseInt(s.next().trim()));
			else
				try {
					if(s.hasNext()) {
						t2 = Integer.parseInt(s.next().trim());
						if(s.hasNext()) {
							t3 = Integer.parseInt(s.next().trim());
							tEdges.add(new Edge(Integer.parseInt(t), t2, t3));
						}
					}
				} catch (NumberFormatException e) {
					e.printStackTrace();
				}
		}
	}

	/**
	 * Fill up a model using the data read from the file
	 * @param vertices
	 */
	public void fillModel(Vertices vertices, Edges edges) {
		for(Edge e : tEdges) {
			edges.addItem(e);
			vertices.addItem(e);
			if(!isDirected())
				vertices.addItem(e.revert());
		}
	}

	public int getNbEdges() {
		return nbEdges;
	}

	public void setNbEdges(int n) {
		nbEdges = n;
		//System.out.println("[+] Setting nbEdges : "+n);
	}

	public int getNbNodes() {
		return nbNodes;
	}

	public void setNbNodes(int n) {
		nbNodes = n;
		//System.out.println("[+] Setting nbNodes : "+n);
	}

	public String getFilePath() {
		return filePath;
	}

	public void setFilePath(String f) {
		filePath = f;
	}
	/**
	 * @return the isDirected
	 */
	public boolean isDirected() {
		return isDirected;
	}
	/**
	 * @param isDirected the isDirected to set
	 */
	public void setDirected(boolean i) {
		isDirected = i;
	}
}
